package services

import (
    "sync"
    "time"
    "runtime"
    "github.com/shirou/gopsutil/v3/cpu"
    "github.com/shirou/gopsutil/v3/mem"
    "github.com/shirou/gopsutil/v3/disk"
)

type SystemMonitor struct {
    mu              sync.RWMutex
    stats           *SystemStats
    updateInterval  time.Duration
    alertThresholds SystemThresholds
    alertService    *AlertService
}

type SystemStats struct {
    CPU       float64   `json:"cpu_usage"`
    Memory    float64   `json:"memory_usage"`
    Disk      float64   `json:"disk_usage"`
    GoRoutines int      `json:"goroutines"`
    Timestamp  time.Time `json:"timestamp"`
}

type SystemThresholds struct {
    CPUThreshold    float64 `json:"cpu_threshold"`
    MemoryThreshold float64 `json:"memory_threshold"`
    DiskThreshold   float64 `json:"disk_threshold"`
}

func NewSystemMonitor(alertService *AlertService) *SystemMonitor {
    sm := &SystemMonitor{
        updateInterval: time.Second * 5,
        alertService:   alertService,
        alertThresholds: SystemThresholds{
            CPUThreshold:    80.0,
            MemoryThreshold: 85.0,
            DiskThreshold:   90.0,
        },
    }
    
    go sm.monitor()
    return sm
}

func (sm *SystemMonitor) monitor() {
    ticker := time.NewTicker(sm.updateInterval)
    for range ticker.C {
        sm.updateStats()
    }
}

func (sm *SystemMonitor) updateStats() {
    sm.mu.Lock()
    defer sm.mu.Unlock()

    stats := &SystemStats{Timestamp: time.Now()}

    // CPU使用率
    if cpuPercent, err := cpu.Percent(0, false); err == nil && len(cpuPercent) > 0 {
        stats.CPU = cpuPercent[0]
        if stats.CPU > sm.alertThresholds.CPUThreshold {
            sm.triggerAlert("HIGH_CPU_USAGE", stats.CPU)
        }
    }

    // 内存使用率
    if vmStat, err := mem.VirtualMemory(); err == nil {
        stats.Memory = vmStat.UsedPercent
        if stats.Memory > sm.alertThresholds.MemoryThreshold {
            sm.triggerAlert("HIGH_MEMORY_USAGE", stats.Memory)
        }
    }

    // 磁盘使用率
    if diskStat, err := disk.Usage("/"); err == nil {
        stats.Disk = diskStat.UsedPercent
        if stats.Disk > sm.alertThresholds.DiskThreshold {
            sm.triggerAlert("HIGH_DISK_USAGE", stats.Disk)
        }
    }

    // Go程序状态
    stats.GoRoutines = runtime.NumGoroutine()

    sm.stats = stats
}

func (sm *SystemMonitor) triggerAlert(alertType string, value float64) {
    sm.alertService.TriggerAlert(Alert{
        Type:     alertType,
        Level:    "warning",
        Value:    value,
        Time:     time.Now(),
        Status:   "active",
    })
}

func (sm *SystemMonitor) GetStats() *SystemStats {
    sm.mu.RLock()
    defer sm.mu.RUnlock()
    return sm.stats
}

func (sm *SystemMonitor) SetThresholds(thresholds SystemThresholds) {
    sm.mu.Lock()
    defer sm.mu.Unlock()
    sm.alertThresholds = thresholds
}
